package com.dy.yunying.biz.service.raffle.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dy.yunying.api.constant.Constant;
import com.dy.yunying.api.entity.hongbao.HbActivityArea;
import com.dy.yunying.api.entity.raffle.RaffleActivity;
import com.dy.yunying.api.entity.raffle.RaffleActivityPrize;
import com.dy.yunying.api.entity.raffle.RaffleExchangeStore;
import com.dy.yunying.api.entity.raffle.RaffleTaskConfig;
import com.dy.yunying.api.enums.SourceTypeEnum;
import com.dy.yunying.api.req.raffle.RaffleActivityEditReq;
import com.dy.yunying.api.req.raffle.RaffleActivityReq;
import com.dy.yunying.api.resp.hongbao.NodeData;
import com.dy.yunying.api.resp.raffle.RaffleActivityRes;
import com.dy.yunying.biz.config.YunYingProperties;
import com.dy.yunying.biz.dao.ads.raffle.RaffleActivityMapper;
import com.dy.yunying.biz.dao.manage.ext.ParentGameDOMapperExt;
import com.dy.yunying.biz.service.hbdata.HbActivityAreaService;
import com.dy.yunying.biz.service.raffle.RaffleActivityPrizeService;
import com.dy.yunying.biz.service.raffle.RaffleActivityService;
import com.dy.yunying.biz.service.raffle.RaffleExchangeStoreService;
import com.dy.yunying.biz.service.raffle.RaffleTaskConfigService;
import com.dy.yunying.biz.utils.DateUtils;
import com.dy.yunying.biz.utils.MapUtils;
import com.google.api.client.util.Lists;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.baomidou.mybatisplus.core.toolkit.StringUtils.underlineToCamel;

/**
 * 抽奖活动配置表服务接口实现
 *
 * @author zjz
 * @since 2022-11-07 18:36:03
 * @description 由 zjz 创建
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class RaffleActivityServiceImpl extends ServiceImpl<RaffleActivityMapper, RaffleActivity> implements RaffleActivityService {

	private final HbActivityAreaService hbActivityAreaService;
	private final ParentGameDOMapperExt parentGameDOMapperExt;
	private final RaffleActivityPrizeService raffleActivityPrizeService;
	private final RaffleTaskConfigService raffleTaskConfigService;
	private final RaffleExchangeStoreService raffleExchangeStoreService;

	@Resource
	private YunYingProperties yunYingProperties;
	/**
	 * 抽奖活动分页列表
	 * @param record
	 * @return
	 */
	@Override
	public R getPage(RaffleActivityReq record){
		QueryWrapper<RaffleActivity> query = getQueryWrapper(record);
		Page<RaffleActivity> page = new Page<>();
		page.setCurrent(record.getCurrent());
		page.setSize(record.getSize());
		Page<RaffleActivityRes> resultPage = new Page<>(page.getCurrent(), page.getSize());
		query.orderByDesc("id");
		Page<RaffleActivity> raffleActivityPage = baseMapper.selectPage(page, query);
		if (CollectionUtil.isEmpty(raffleActivityPage.getRecords())) {
			return R.ok(resultPage);
		}
		String raffleActivityLinkage = yunYingProperties.getRaffleActivityLinkage();
		resultPage.setTotal(raffleActivityPage.getTotal());
		resultPage.setCountId(raffleActivityPage.getCountId());
		resultPage.setPages(raffleActivityPage.getPages());
		List<Long> activityIdResult = raffleActivityPage.getRecords().stream().map(RaffleActivity::getId).collect(Collectors.toList());
		//游戏区服
		List<HbActivityArea> allActivityAreaList = hbActivityAreaService.getBaseMapper().selectList(new QueryWrapper<HbActivityArea>().in("activity_id", activityIdResult).eq("source_type", SourceTypeEnum.RAFFLE.getType()).orderByAsc("area_id"));

		List<NodeData> parentGameList = parentGameDOMapperExt.selectMainGameList();
		List<RaffleActivityRes> resultList = new ArrayList<>();
		//组合 游戏区服 数据
		raffleActivityPage.getRecords().forEach( buoyRule -> {
			final RaffleActivityRes vo = JSON.parseObject(JSON.toJSONString(buoyRule), RaffleActivityRes.class);
			vo.setParentGameName(getParentGameById(vo.getParentGameId(), parentGameList));
			List<Long> activityAreaList = allActivityAreaList.stream().filter(ac -> ac.getActivityId().equals(vo.getId())).map(HbActivityArea::getAreaId).collect(Collectors.toList());
			List<Long> activityAreaAll = new ArrayList<>();
			activityAreaAll.add(0L);
			vo.setAreaDataList(CollectionUtils.isNotEmpty(activityAreaList)?activityAreaList:activityAreaAll);
			//列表转跳展示  LinkageList
			List<String> linkageList = new ArrayList<>();
			linkageList.add(raffleActivityLinkage + vo.getId());
			vo.setLinkageList(linkageList);
			resultList.add(vo);
		});
		resultPage.setRecords(resultList);
		return R.ok(resultPage);
	}

	/**
	 * 列表
	 * @param record
	 * @return
	 */
	@Override
	public R  getList(RaffleActivityReq record){
		List<Map<String,Object>> mapList=this.listMaps(Wrappers.<RaffleActivity>lambdaQuery().eq(RaffleActivity::getDeleted, 0).notIn(RaffleActivity::getActivityStatus,3).select(RaffleActivity::getId,RaffleActivity::getActivityName));
		List<Map<String, Object>> transMap=Lists.newArrayList();
		 if(CollectionUtils.isNotEmpty(mapList)){
			 mapList.forEach(m->{
				 transMap.add(MapUtils.toReplaceKeyLow(m));

			 });
		 }
		return R.ok(transMap);
	}

	/**
	 * 将map对于的key转换为驼峰格式
	 * @param map
	 * @return
	 */

	private static Map<String, Object> toReplaceKeyLow(Map<String, Object> map) {
		Map reMap = new HashMap();

		if (map != null) {
			Iterator var2 = map.entrySet().iterator();

			while (var2.hasNext()) {
				Map.Entry<String, Object> entry = (Map.Entry) var2.next();
				reMap.put(underlineToCamel((String) entry.getKey()), map.get(entry.getKey()));
			}

			map.clear();
		}

		return reMap;
	}

	private QueryWrapper<RaffleActivity> getQueryWrapper(RaffleActivityReq record) {
		QueryWrapper<RaffleActivity> query = new QueryWrapper<>();
		if (StringUtils.isNotBlank(record.getStartDate())) {
			query.ge("DATE_FORMAT(start_time,'%Y-%m-%d')", record.getStartDate());
		}
		if (StringUtils.isNotBlank(record.getEndDate())) {
			query.le("DATE_FORMAT(start_time,'%Y-%m-%d')", record.getEndDate());
		}
		if (record.getActivityStatus()!=null) {
			query.eq("activity_status", record.getActivityStatus());
		}
		if (record.getParentGameId()!=null) {
			query.eq("parent_game_id", record.getParentGameId());
		}
		query.eq("deleted", Constant.DEL_NO);
		if (StringUtils.isNotBlank(record.getNameAndId())) {
			query.and(wrapper ->
					wrapper
						.or()
						.like("activity_name", record.getNameAndId())
						.or()
						.eq("id",record.getNameAndId()));
		}
		return query;
	}

	private String getParentGameById(Long id, List<NodeData> parentGameList) {
		return parentGameList.stream().filter(node -> id.toString().equals(node.getNodeId()))
				.findFirst().map(NodeData::getNodeName).orElse("");
	}

	/**
	 * 抽奖活动新增-编辑
	 * @param record
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class, transactionManager = "adsTransactionManager")
	@Override
	public R createEdit(RaffleActivityEditReq record){
		String message = "";
		if (StringUtils.isBlank(record.getKvpic())) {
			record.setKvpic(yunYingProperties.getRaffleActivityKvpic());
		}
		RaffleActivity raffleActivity = new RaffleActivity();
		BeanUtils.copyProperties(record, raffleActivity);
		raffleActivity.setStartTime(DateUtils.stringToDate(record.getStartTime(), DateUtils.YYYY_MM_DD_HH_MM_SS));
		raffleActivity.setFinishTime(DateUtils.stringToDate(record.getFinishTime(), DateUtils.YYYY_MM_DD_HH_MM_SS));
		if (record.getId()==null) {
			raffleActivity.setCreateTime(new Date());
			raffleActivity.setCreateId(Objects.requireNonNull(SecurityUtils.getUser()).getId().longValue());
			// 新增
			this.save(raffleActivity);
			record.setId(raffleActivity.getId());
			message = "新增抽奖活动成功";
			List<RaffleActivityPrize> raffleActivityPrizeList = new ArrayList<>(yunYingProperties.getRaffleActivityNum());
			for (int i = 1; i <= yunYingProperties.getRaffleActivityNum(); i++){
				RaffleActivityPrize ra=new RaffleActivityPrize();
				ra.setActivityId(raffleActivity.getId());
				ra.setPrizeGear(i);
				ra.setPrizeName("奖品"+i);
				ra.setPrizeGrade("品阶"+i);
				ra.setPrizeWeight(new BigDecimal("0"));
				ra.setPrizeIconUrl("-1");
				ra.setPrizeType(1);
				ra.setGiftType(1);
				ra.setPrizeSingleLimit(1);
				ra.setPrizeInventory(0);
				ra.setCreateTime(new Date());
				ra.setUpdateTime(new Date());
				ra.setCreateId(Objects.requireNonNull(SecurityUtils.getUser()).getId().longValue());
				ra.setUpdateId(Objects.requireNonNull(SecurityUtils.getUser()).getId().longValue());
				raffleActivityPrizeList.add(ra);
			}
			raffleActivityPrizeService.saveBatchList(raffleActivityPrizeList);
		} else {
			raffleActivity.setUpdateTime(new Date());
			raffleActivity.setUpdateId(Objects.requireNonNull(SecurityUtils.getUser()).getId().longValue());
			// 编辑
			this.updateById(raffleActivity);
			message = "编辑抽奖活动成功";
		}
		if (CollectionUtils.isNotEmpty(record.getAreaList())) {
			// 更新区服关系
			List<HbActivityArea> insertList = Lists.newArrayList();
			if(record.getAreaList().contains(0L)){
				HbActivityArea activityArea  = new HbActivityArea();
				activityArea.setActivityId(record.getId());
				activityArea.setSourceType(SourceTypeEnum.RAFFLE.getType());
				activityArea.setGameId(record.getParentGameId());
				activityArea.setAreaRange(1);
				activityArea.setCreateTime(new Date());
				activityArea.setCreateId(SecurityUtils.getUser().getId().longValue());
				activityArea.setUpdateTime(new Date());
				activityArea.setUpdateId(SecurityUtils.getUser().getId().longValue());
				insertList.add(activityArea);
			}else {
				record.getAreaList().forEach(a -> {
					HbActivityArea activityArea = new HbActivityArea();
					activityArea.setActivityId(record.getId());
					activityArea.setSourceType(SourceTypeEnum.RAFFLE.getType());
					activityArea.setGameId(record.getParentGameId());
					activityArea.setAreaId(a);
					activityArea.setAreaRange(2);
					activityArea.setCreateTime(new Date());
					activityArea.setCreateId(SecurityUtils.getUser().getId().longValue());
					activityArea.setUpdateTime(new Date());
					activityArea.setUpdateId(SecurityUtils.getUser().getId().longValue());
					insertList.add(activityArea);
				});
			}
			hbActivityAreaService.remove(new QueryWrapper<HbActivityArea>().eq("activity_id", record.getId()).eq("source_type", SourceTypeEnum.RAFFLE.getType()));
			// 批量新增
			hbActivityAreaService.saveBatchList(insertList);
		}
		return R.ok(message);
	}
	/**
	 * 复制抽奖活动
	 * @param id
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class, transactionManager = "adsTransactionManager")
	public R copy(Long id){
		RaffleActivity raffleActivity = this.getById(id);
		if (raffleActivity == null){
			return R.failed("抽奖活动主键id不存在");
		}
		//复制浮标规则
		raffleActivity.setId(null);
		raffleActivity.setActivityStatus(1);
		raffleActivity.setCreateId(Objects.requireNonNull(SecurityUtils.getUser()).getId().longValue());
		raffleActivity.setCreateTime(new Date());
		//
		this.save(raffleActivity);
		//复制游戏渠道区服
		List<HbActivityArea> allNoticeAreaList = hbActivityAreaService.getBaseMapper().selectList(new QueryWrapper<HbActivityArea>().eq("activity_id", id).eq("source_type", SourceTypeEnum.RAFFLE.getType()).eq("deleted",0));
		allNoticeAreaList.forEach(a -> {
			a.setActivityId(raffleActivity.getId());
			a.setId(null);
			a.setCreateId(SecurityUtils.getUser().getId().longValue());
			a.setCreateTime(new Date());
			a.setUpdateId(SecurityUtils.getUser().getId().longValue());
			a.setUpdateTime(new Date());
		});
		hbActivityAreaService.saveBatchList(allNoticeAreaList);

		List<RaffleActivityPrize> raffleActivityPrizeList = raffleActivityPrizeService.getBaseMapper().selectList(new QueryWrapper<RaffleActivityPrize>().eq("activity_id",id).eq("deleted",0));
		raffleActivityPrizeList.forEach(a->{
			a.setActivityId(raffleActivity.getId());
			a.setId(null);
			a.setPrizeInventory(0);
			a.setPrizeCostNum(0);
			a.setGiftTotalNum(0);
			a.setCreateId(SecurityUtils.getUser().getId().longValue());
			a.setCreateTime(new Date());
			a.setUpdateId(SecurityUtils.getUser().getId().longValue());
			a.setUpdateTime(new Date());
		});
		raffleActivityPrizeService.saveBatchList(raffleActivityPrizeList);


		List<RaffleTaskConfig> raffleTaskConfigList = raffleTaskConfigService.getBaseMapper().selectList(new QueryWrapper<RaffleTaskConfig>().eq("activity_id",id).eq("deleted",0));
		raffleTaskConfigList.forEach(a->{
			a.setActivityId(raffleActivity.getId());
			a.setId(null);
			a.setCreateId(SecurityUtils.getUser().getId().longValue());
			a.setCreateTime(new Date());
			a.setUpdateId(SecurityUtils.getUser().getId().longValue());
			a.setUpdateTime(new Date());
		});
		raffleTaskConfigService.saveBatchList(raffleTaskConfigList);

		List<RaffleExchangeStore> raffleExchangeStoreList = raffleExchangeStoreService.getBaseMapper().selectList(new QueryWrapper<RaffleExchangeStore>().eq("activity_id",id).eq("deleted",0));
		raffleExchangeStoreList.forEach(a->{
			a.setActivityId(raffleActivity.getId());
			a.setId(null);
			a.setProductInventory(0);
			a.setGiftTotalNum(0);
			a.setProductCostNum(0);
			a.setCreateId(SecurityUtils.getUser().getId().longValue());
			a.setCreateTime(new Date());
			a.setUpdateId(SecurityUtils.getUser().getId().longValue());
			a.setUpdateTime(new Date());
		});
		raffleExchangeStoreService.saveBatchList(raffleExchangeStoreList);
		return R.ok();
	}

	/**
	 * 批量更新kv图
	 * @param record
	 * @return
	 */
	@Override
	public R batchKvpic(RaffleActivityEditReq record){
		List<RaffleActivity> raffleActivityList = Lists.newArrayList();
		for (String item : Arrays.asList(record.getIds().split(","))){
			RaffleActivity raffleActivity = new RaffleActivity();
			raffleActivity.setId(Long.valueOf(item));
			raffleActivity.setKvpic(record.getKvpic());
			raffleActivityList.add(raffleActivity);
		}
		return this.updateBatchById(raffleActivityList) ? R.ok() : R.failed();
	}

	/**
	 * 更新状态
	 * @param record
	 * @return
	 */
	@Override
	public R activityStatus(RaffleActivityEditReq record){
		if (2 == record.getActivityStatus()){
			List<RaffleActivityPrize> raffleActivityList = raffleActivityPrizeService.list(Wrappers.<RaffleActivityPrize>lambdaQuery()
					.eq(RaffleActivityPrize::getActivityId, record.getId())
					.eq(RaffleActivityPrize::getPrizeIconUrl, "-1")
					.eq(RaffleActivityPrize::getDeleted, 0));
			if (CollectionUtils.isNotEmpty(raffleActivityList)){
				return R.failed("奖品未配置");
			}

			List<RaffleActivityPrize> raffleActivityPrizeList = raffleActivityPrizeService.list(Wrappers.<RaffleActivityPrize>lambdaQuery()
					.eq(RaffleActivityPrize::getActivityId, record.getId())
					.eq(RaffleActivityPrize::getPrizeInventory, "-1")
					.eq(RaffleActivityPrize::getPrizeSingleLimit, "-1")
					.gt(RaffleActivityPrize::getPrizeWeight, 0)
					.eq(RaffleActivityPrize::getDeleted, 0));
			if (CollectionUtils.isEmpty(raffleActivityPrizeList)){
				return R.failed("至少有一个，概率大于0且库存无上限且个人领取无上限的奖品");
			}

			RaffleActivity raffleActivity = this.getById(record.getId());
			if (1 == raffleActivity.getEnableExchange() && 1 == raffleActivity.getExchangeType()){
				List<RaffleExchangeStore> raffleExchangeStoreList = raffleExchangeStoreService.list(Wrappers.<RaffleExchangeStore>lambdaQuery()
						.eq(RaffleExchangeStore::getActivityId, raffleActivity.getId())
						.ne(RaffleExchangeStore::getProductInventory, 0)
						.eq(RaffleExchangeStore::getDeleted, 0));
				if (CollectionUtils.isEmpty(raffleExchangeStoreList)){
					return R.failed("请先配置兑换商品并且设置库存");
				}
			}
			if (raffleActivity.getFinishTime().getTime() < new Date().getTime()){
				return R.failed("活动结束时间小于当前时间无法上线");
			}
		}
		return this.updateById(new RaffleActivity().setId(record.getId()).setActivityStatus(record.getActivityStatus())) ? R.ok() : R.failed();
	}
}
